package com.hnrd.crud.interceptor;

import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.hnrd.crud.annotation.Permissions;
import com.hnrd.crud.mapper.TUserMapper;
import com.hnrd.crud.pojo.TUser;
import com.hnrd.crud.shiro.ActiveSession;
import com.hnrd.crud.utils.JWTTokenUtil;
import com.hnrd.crud.utils.ResponesUtils;

@Component
public class UserInterceptor implements HandlerInterceptor{
	@Autowired
	private TUserMapper tUserMapper;
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if (request.getMethod().equals("OPTIONS")) {
			return true;
		}
		ResponesUtils.SetHttpServletResponse(response);
		try {
		} catch (Exception e) {
			throw new Exception();
		}
		String token = request.getHeader("Authorization");
		if (token == null) {
			throw new JWTDecodeException("未查询到token信息！");		
		}
		boolean valdateToken;
		try {
			valdateToken = JWTTokenUtil.validateToken(token);
		} catch (Exception e) {
			throw new JWTDecodeException("token无效！");
		}
		if (!valdateToken) {
			throw new JWTDecodeException("token过期！");
		}
		if (valdateToken) {//如果token没有过期
			/**
			 * 解析token获取用户信息
			 */
			String username = JWTTokenUtil.getUsername(token);
			/**
			 * 获取方法上注解上的权限信息
			 */
			TUser user= tUserMapper.selectByUsername(username);
			if (user!=null) {
				HandlerMethod  handlerMethod = (HandlerMethod)handler;
				Permissions permissions = handlerMethod.getMethodAnnotation(Permissions.class);	
				
				if (permissions!=null) {
					String[] methodPermission = permissions.permission();
					SessionKey sessionKey = (SessionKey) ActiveSession.map.get(username);
					Session session= null;
					try {
						session = SecurityUtils.getSecurityManager().getSession(sessionKey);
					} catch (Exception e) {
						throw new LoginException("用户未登录！");
					}
					
					Subject subject =(Subject) session.getAttribute(token);
					try {
						subject.checkPermissions(methodPermission);
					} catch (Exception e) {
						throw new AuthenticationException("该用户没有权限！");
					}
					return true;
				}
			}
		}
		throw new JWTDecodeException("未知错误!");		
	}
}
